﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.ComponentModel;

namespace Simulator
{
    /// <summary>
    /// класс Block является родительским для всех
    /// блоков имитационной модели. Name - его уникальное
    /// имя в текущей диаграмме.
    /// Сущности идут между блоками, при этом отправить сущность
    /// в блок можно только с помощью функции putEntity
    /// </summary>
    [Serializable]
    public abstract class Block 
    {
        /// <summary>
        /// Уникальное имя-идентификатор
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// Текст, отображаемый на диаграмме
        /// </summary>
        public string Text { get; set; }

        private Block next;
        private Block prev;

        /// <summary>
        /// Блок, в который поступают сущности после текущего блока
        /// </summary>
        public Block Next
        {
            get { return next; }
            set { next = value; }
        }

        /// <summary>
        /// Блок, из которого поступают сущности в текущий блок
        /// </summary>
        public Block Prev
        {
            get { return prev; }
            set { prev = value; }
        }
        /// <summary>
        /// Положить сущность в блок
        /// </summary>
        /// <param name="e">Cущность, которую кладем</param>
        public abstract void PutEntity(ref Entity e);
        /// <summary>
        /// Очистить список сущностей в блоке
        /// </summary>
        public abstract void ClearEntities();
        /// <summary>
        /// Клонировать объект "блок" с текущими полями
        /// </summary>
        /// <returns>Клонированный экземпляр</returns>
        public Block Clone()
        {
            //we create a new instance of this specific type.            
            object newInstance = Activator.CreateInstance(this.GetType());

            //We get the array of properties for the new type instance.            
            PropertyInfo[] properties = newInstance.GetType().GetProperties();

            int i = 0;

            foreach (PropertyInfo pi in this.GetType().GetProperties())
            {
                TypeConverter conv = TypeDescriptor.GetConverter(pi.PropertyType);
                if(pi.CanWrite)
                    properties[i].SetValue(newInstance, pi.GetValue(this, null), null);
                i++;
            }
            return (newInstance as Block);
        }
    }
}
